4 // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
6 // The use and distribution terms for this software are contained in the file
7 // named license.txt, which can be found in the root of this distribution.
8 // By using this software in any fashion, you are agreeing to be bound by the
9 // terms of this license.
11 // You must not remove this notice, or any other, from this software.
15 #include <rotor_pal.h>
16 #include <palstartup.h>
18 #define BINPLACE_ERR 77
24 BOOL fSetupModeAllFiles
;
25 BOOL fSetupModeScriptFile
;
28 BOOL fMakeErrorOnDumpCopy
;
31 BOOL fChangeAsmsToRetailForSymbols
;
36 LPSTR CurrentImageName
;
40 LPSTR NormalPlaceSubdir
;
41 LPSTR CommandScriptName
;
43 LPSTR PrivateSymbolFilePath
;
48 FILE *CommandScriptFile
;
49 CHAR
* gDelayLoadModule
;
50 CHAR
* gDelayLoadHandler
;
51 CHAR gFullFileName
[MAX_PATH
+1];
52 UCHAR SetupFilePath
[ MAX_PATH
+1 ];
53 UCHAR DebugFilePath
[ MAX_PATH
+1 ];
54 UCHAR PlaceFilePath
[ MAX_PATH
+1 ];
55 UCHAR DefaultSymbolFilePath
[ MAX_PATH
+1 ];
56 UCHAR szAltPlaceRoot
[ MAX_PATH
+1 ];
65 #define DEFAULT_PLACE_FILE "\\public\\sdk\\lib\\placefil.txt"
66 #define DEFAULT_NTROOT "\\nt"
67 #define DEFAULT_NTDRIVE "c:"
68 #define DEFAULT_DUMP "dump"
69 #define DEFAULT_LCDIR "LcINF"
71 typedef struct _CLASS_TABLE
{
74 } CLASS_TABLE
, *PCLASS_TABLE
;
84 LPSTR DestinationSubdir
,
85 LPSTR DestinationFilePart
90 LPSTR DestinationFile
,
91 LPSTR SourceFileName
, // Used for redist case
92 BOOL CopyFromSourceOnly
,
97 LPSTR DestinationFile
,
98 LPSTR SourceFileName
, // Used for redist case
99 BOOL CopyFromSourceOnly
,
104 BinplaceCopyManifest (
105 LPSTR DestinationFile
,
106 LPSTR SourceFileName
, // Used for redist case
107 BOOL CopyFromSourceOnly
,
120 IN LPSTR FullFileName
,
121 IN LPSTR FileNamePart
,
129 IN LPSTR SourceFullName
,
130 IN LPSTR SourceFilePart
,
131 OUT PBOOL FoundInTree
135 // This was way too slow. Just say we didn't find the file.
137 *FoundInTree
= FALSE
;
144 OUT PWIN32_FIND_DATA FindData
149 CLASS_TABLE CommonClassTable
[] = {
155 CLASS_TABLE i386SpecificClassTable
[] = {
157 {"printer","system32\\spool\\drivers\\w32x86"},
158 {"prtprocs","system32\\spool\\prtprocs\\w32x86"},
163 CLASS_TABLE ia64SpecificClassTable
[] = {
165 {"printer","system32\\spool\\drivers\\w32ia64"},
166 {"prtprocs","system32\\spool\\prtprocs\\w32ia64"},
171 // Names of sections in layout.inx
173 LPCSTR szSourceDisksFiles
= "SourceDisksFiles";
174 LPCSTR szSourceDisksX86
= "SourceDisksFiles.x86";
175 LPCSTR szSourceDisksIA64
= "SourceDisksFiles.ia64";
177 typedef struct _PLACE_FILE_RECORD
{
180 } PLACE_FILE_RECORD
, *PPLACE_FILE_RECORD
;
182 int MaxNumberOfRecords
;
184 PPLACE_FILE_RECORD PlaceFileRecords
;
192 PPLACE_FILE_RECORD p1
;
193 PPLACE_FILE_RECORD p2
;
195 p1
= (PPLACE_FILE_RECORD
)e1
;
196 p2
= (PPLACE_FILE_RECORD
)e2
;
198 return (strcmp(p1
->FileNameEntry
,p2
->FileNameEntry
));
201 CHAR PlaceFileDir
[4096];
202 CHAR PlaceFileClass
[4096];
203 CHAR PlaceFileEntry
[4096];
206 SortPlaceFileRecord()
209 PPLACE_FILE_RECORD NewRecords
;
212 MaxNumberOfRecords
= 0;
215 // get space for 6k records. Grow if need to.
217 MaxNumberOfRecords
= 7000;
218 PlaceFileRecords
= (PPLACE_FILE_RECORD
) malloc( sizeof(*PlaceFileRecords
)*MaxNumberOfRecords
);
219 if ( !PlaceFileRecords
) {
223 if (fseek(PlaceFile
,0,SEEK_SET
)) {
224 free(PlaceFileRecords
);
225 PlaceFileRecords
= NULL
;
229 while (fgets(PlaceFileDir
,sizeof(PlaceFileDir
),PlaceFile
)) {
231 PlaceFileEntry
[0] = '\0';
232 PlaceFileClass
[0] = '\0';
236 // "%s %[A-Za-z0-9.,_!@#\\$+=%^&()~ -]s",
242 if (cfield
<= 0 || PlaceFileEntry
[0] == ';') {
246 PlaceFileRecords
[NumberOfRecords
].FileNameEntry
= (LPSTR
) malloc( strlen(PlaceFileEntry
)+1 );
247 PlaceFileRecords
[NumberOfRecords
].FileClass
= (LPSTR
) malloc( strlen(PlaceFileClass
)+1 );
248 if (!PlaceFileRecords
[NumberOfRecords
].FileClass
|| !PlaceFileRecords
[NumberOfRecords
].FileNameEntry
) {
249 if (PlaceFileRecords
[NumberOfRecords
].FileClass
)
250 free(PlaceFileRecords
[NumberOfRecords
].FileClass
);
251 if (PlaceFileRecords
[NumberOfRecords
].FileNameEntry
)
252 free(PlaceFileRecords
[NumberOfRecords
].FileNameEntry
);
253 free(PlaceFileRecords
);
254 PlaceFileRecords
= NULL
;
257 strcpy(PlaceFileRecords
[NumberOfRecords
].FileNameEntry
,PlaceFileEntry
);
258 strcpy(PlaceFileRecords
[NumberOfRecords
].FileClass
,PlaceFileClass
);
260 if ( NumberOfRecords
>= MaxNumberOfRecords
) {
261 MaxNumberOfRecords
+= 200;
262 NewRecords
= (PPLACE_FILE_RECORD
) realloc(
264 sizeof(*PlaceFileRecords
)*MaxNumberOfRecords
267 PlaceFileRecords
= NULL
;
270 PlaceFileRecords
= NewRecords
;
273 qsort((void *)PlaceFileRecords
,(size_t)NumberOfRecords
,(size_t)sizeof(*PlaceFileRecords
),pfcomp
);
278 LookupPlaceFileRecord(
288 // Lookup the name using a binary search.
291 if ( !PlaceFileRecords
) {
296 High
= NumberOfRecords
- 1;
297 while (High
>= Low
) {
300 // Compute the next probe index and compare the import name
301 // with the export name entry.
304 Middle
= (Low
+ High
) >> 1;
305 Result
= _stricmp(FileName
, PlaceFileRecords
[Middle
].FileNameEntry
);
310 } else if (Result
> 0) {
321 return &PlaceFileRecords
[Middle
];
326 MakeSureDirectoryPathExists(
333 // Make a copy of the string for editing.
335 DirCopy
= (LPSTR
)malloc(strlen(DirPath
) + 1);
341 strcpy(DirCopy
, DirPath
);
345 // If the second character in the path is "\", then this is a UNC
346 // path, and we should skip forward until we reach the 2nd \ in the path.
348 if ((*p
== '\\') && (*(p
+1) == '\\')) {
349 p
++; // Skip over the first \ in the name.
350 p
++; // Skip over the second \ in the name.
352 // Skip until we hit the first "\" (\\Server\).
354 while (*p
&& *p
!= '\\') {
364 // Skip until we hit the second "\" (\\Server\Share\).
366 while (*p
&& *p
!= '\\') {
370 // Advance over it also.
377 // Not a UNC. See if it's <drive>:
378 if (*(p
+1) == ':' ) {
383 // If it exists, skip over the root specifier
385 if (*p
&& (*p
== '\\')) {
393 dw
= GetFileAttributesA(DirCopy
);
394 // Nothing exists with this name. Try to make the directory name and error if unable to.
395 if ( dw
== 0xffffffff ) {
396 if ( !CreateDirectory(DirCopy
,NULL
) ) {
397 if( GetLastError() != ERROR_ALREADY_EXISTS
) {
403 if ( (dw
& FILE_ATTRIBUTE_DIRECTORY
) != FILE_ATTRIBUTE_DIRECTORY
) {
404 // Something exists with this name, but it's not a directory... Error
426 char c
, *p
, *OverrideFlags
, *s
, **newargv
;
432 fKeepAttributes
= FALSE
;
436 NormalPlaceSubdir
= NULL
;
443 if (!(PlaceFileName
= getenv( "BINPLACE_PLACEFILE" ))) {
444 if ((PlaceFileName
= getenv("_NTDRIVE")) == NULL
) {
445 PlaceFileName
= DEFAULT_NTDRIVE
;
447 strcpy((PCHAR
) PlaceFilePath
, PlaceFileName
);
448 if ((PlaceFileName
= getenv("_NTROOT")) == NULL
) {
449 PlaceFileName
= DEFAULT_NTROOT
;
451 strcat((PCHAR
) PlaceFilePath
, PlaceFileName
);
452 strcat((PCHAR
) PlaceFilePath
, DEFAULT_PLACE_FILE
);
453 PlaceFileName
= (PCHAR
) PlaceFilePath
;
457 if (!(BinplaceLcDir
= getenv( "BINPLACE_LCDIR" ))) {
458 BinplaceLcDir
= DEFAULT_LCDIR
;
463 CurrentImageName
= NULL
;
465 OverrideFlags
= getenv( "BINPLACE_OVERRIDE_FLAGS" );
466 if (OverrideFlags
!= NULL
) {
470 while (*s
&& *s
<= ' ')
483 newargv
= malloc( (argc
+ n
+ 1) * sizeof( char * ) );
484 memcpy( &newargv
[n
], argv
, argc
* sizeof( char * ) );
486 argv
[ 0 ] = argv
[ n
];
489 for (i
=1; i
<=n
; i
++) {
490 while (*s
&& *s
<= ' ')
502 if (_stricmp(p
+ 1, "ChangeAsmsToRetailForSymbols") == 0) {
503 fChangeAsmsToRetailForSymbols
= TRUE
;
506 switch (toupper( c
)) {
514 NormalPlaceSubdir
= *argv
;
518 if (*(p
+1) == 'I' || *(p
+1) == 'i') {
523 ImageCheck
.RC
= atoi(p
);
524 if (!ImageCheck
.RC
) {
525 fprintf( stderr
, "BINPLACE : error BNP0000: Invalid return code for -CI option\n");
532 if (*p
++ == ',') ImageCheck
.Argc
++;
533 // last option plus extra args for Image file and Argv NULL
534 ImageCheck
.Argc
+= 3;
535 ImageCheck
.Argv
= malloc( ImageCheck
.Argc
* sizeof( void * ) );
536 for ( i
= 0; i
<= ImageCheck
.Argc
- 3; i
++) {
537 ImageCheck
.Argv
[i
] = q
;
538 while (*q
!= ',' && *q
!= '\0') q
++;
542 ImageCheck
.Argv
[ImageCheck
.Argc
-1] = NULL
;
550 DumpOverride
= *argv
;
563 fKeepAttributes
= TRUE
;
568 fMakeErrorOnDumpCopy
= TRUE
;
577 if (PlaceRootName
!= NULL
) {
578 strcpy(szAltPlaceRoot
,PlaceRootName
);
579 strcat(szAltPlaceRoot
,"\\");
580 strcat(szAltPlaceRoot
,*argv
);
581 PlaceRootName
= szAltPlaceRoot
;
587 PlaceFileName
= *argv
;
596 PlaceRootName
= *argv
;
601 SymbolFilePath
= *argv
;
625 fprintf( stderr
, "BINPLACE : error BNP0000: Invalid switch - /%c\n", c
);
634 "usage: binplace [switches] image-names... \n"
635 "where: [-?] display this message\n"
636 " [-b subdir] put file in subdirectory of normal place\n"
637 " [-d dump-override]\n"
638 " [-e] don't exit if a file in list could not be binplaced\n"
639 " [-k] keep attributes (don't turn off archive)\n"
640 " [-o place-root-subdir] alternate project subdirectory\n"
642 " [-q] suppress writing to log file %BINPLACE_LOG%\n"
644 " [-s Symbol file path] split symbols from image files\n"
646 " [-v] verbose output\n"
647 " [-ci <rc,app,-arg0,-argv1,-argn>]\n"
648 " rc=application error return code,\n"
649 " app=application used to check images,\n"
650 " -arg0..-argn=application options\n"
652 "BINPLACE looks for the following environment variable names:\n"
653 " BINPLACE_OVERRIDE_FLAGS - may contain additional switches\n"
654 " BINPLACE_PLACEFILE - default value for -p flag\n"
662 WIN32_FIND_DATA FindData
;
665 if (!PlaceRootName
) {
666 // If there's no root, just exit.
671 h
= FindFirstFile(p
,&FindData
);
672 if (h
!= INVALID_HANDLE_VALUE
) {
674 if (FindData
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
676 fprintf(stdout
,"BINPLACE : warning BNP0000: ignoring directory %s\n",p
);
682 CurrentImageName
= p
;
686 // If the master place file has not been opened, open
691 PlaceFile
= fopen(PlaceFileName
, "rt");
693 fprintf(stderr
,"BINPLACE : fatal error BNP0000: fopen of placefile %s failed %d\n",PlaceFileName
,GetLastError());
699 if (PlaceRootName
== NULL
) {
700 fprintf(stderr
,"BINPLACE : fatal error BNP0000: Place Root not defined - exiting.\n");
704 // If the SymbolFilePath has not been set, make a default value.
705 if (!SymbolFilePath
) {
706 strcpy(DefaultSymbolFilePath
, PlaceRootName
);
707 strcat(DefaultSymbolFilePath
, "\\symbols");
708 SymbolFilePath
= DefaultSymbolFilePath
;
711 if ( !PlaceTheFile() ) {
713 fprintf(stderr
,"BINPLACE : error BNP0000: Unable to place file %s.\n",CurrentImageName
);
715 fprintf(stderr
,"BINPLACE : fatal error BNP0000: Unable to place file %s - exiting.\n",CurrentImageName
);
729 CHAR FullFileName
[MAX_PATH
+1];
730 LPSTR PlaceFileNewName
;
733 LPSTR PlaceFileClassPart
;
736 PCLASS_TABLE ClassTablePointer
;
738 BOOL fCopyResult
= FALSE
;
740 BOOL PutInDebug
= FALSE
;
741 BOOL PutInLcDir
= FALSE
;
743 cb
= GetFullPathName(CurrentImageName
,MAX_PATH
+1,FullFileName
,&FilePart
);
745 if (!cb
|| cb
> MAX_PATH
+1) {
746 fprintf(stderr
,"BINPLACE : fatal error BNP0000: GetFullPathName failed %d\n",GetLastError());
752 fprintf(stdout
,"BINPLACE : warning BNP0000: Looking at file %s\n",FilePart
);
755 Extension
= strrchr(FilePart
,'.');
757 if (!_stricmp(Extension
,".DBG")) {
760 else if (!_stricmp(Extension
,".LC")) {
767 if (fseek(PlaceFile
,0,SEEK_SET
)) {
768 fprintf(stderr
,"BINPLACE : fatal error BNP0000: fseek(PlaceFile,0,SEEK_SET) failed %d\n",GetLastError());
771 while (fgets(PlaceFileDir
,sizeof(PlaceFileDir
),PlaceFile
)) {
773 PlaceFileEntry
[0] = '\0';
774 PlaceFileClass
[0] = '\0';
778 // "%s %[A-Za-z0-9.,_!@#\\$+=%^&()~ -]s",
784 if (cfield
<= 0 || PlaceFileEntry
[0] == ';') {
788 if ((PlaceFileNewName
= strchr(PlaceFileEntry
,'!'))) {
789 *PlaceFileNewName
++ = '\0';
792 if (!_stricmp(FilePart
,PlaceFileEntry
)) {
794 // now that we have the file and class, search the
795 // class tables for the directory.
797 Separator
= PlaceFileClass
- 1;
800 PlaceFileClassPart
= Separator
+1;
801 Separator
= strchr(PlaceFileClassPart
,':');
807 // If the class is "retail" and we're in Setup mode,
808 // handle this file specially. Setup mode is used to
809 // incrementally binplace files into an existing installation.
811 SetupFilePath
[0] = '\0';
813 PlaceFileDir
[0]='\0';
815 ClassTablePointer
= &CommonClassTable
[0];
816 while (ClassTablePointer
->ClassName
) {
817 if (!_stricmp(ClassTablePointer
->ClassName
,PlaceFileClassPart
)) {
818 strcpy(PlaceFileDir
,ClassTablePointer
->ClassLocation
);
829 // Search Specific classes
831 // We need to support cross compiling here.
834 ClassTablePointer
= &i386SpecificClassTable
[0];
835 if ((platform
= getenv("IA64")) != NULL
) {
836 ClassTablePointer
= &ia64SpecificClassTable
[0];
838 while (ClassTablePointer
->ClassName
) {
840 if (!_stricmp(ClassTablePointer
->ClassName
,PlaceFileClassPart
)) {
841 strcpy(PlaceFileDir
,ClassTablePointer
->ClassLocation
);
855 // Still not found in class table. Use the class as the
860 fprintf(stderr
,"BINPLACE : warning BNP0000: Class %s Not found in Class Tables\n",PlaceFileClassPart
);
862 if ((asterisk
= strchr(PlaceFileClassPart
, '*'))) {
864 // Expand * to platform
871 PlatformPath
= TEXT("i386");
872 if ((platform
= getenv("IA64")) != NULL
) {
873 PlatformPath
= TEXT("ia64");
874 } else if ((platform
= getenv("AMD64")) != NULL
) {
876 PlatformPath
= TEXT("amd64");
879 strncpy(PlaceFileDir
,PlaceFileClassPart
, (int)(asterisk
- PlaceFileClassPart
));
880 strcpy(PlaceFileDir
+ (asterisk
- PlaceFileClassPart
), PlatformPath
);
881 strcpy(PlaceFileDir
+ (asterisk
- PlaceFileClassPart
) + PlatformSize
, asterisk
+ 1);
884 strcpy(PlaceFileDir
,PlaceFileClassPart
);
888 if (SetupFilePath
[0] == '\0') {
889 strcpy(SetupFilePath
, PlaceFileDir
);
890 strcat(SetupFilePath
, "\\");
891 strcat(SetupFilePath
, FilePart
);
894 if (NormalPlaceSubdir
) {
895 strcat(PlaceFileDir
,"\\");
896 strcat(PlaceFileDir
,NormalPlaceSubdir
);
899 fCopyResult
= CopyTheFile(FullFileName
,FilePart
,PlaceFileDir
,PlaceFileNewName
);
910 if (fMakeErrorOnDumpCopy
) {
911 fprintf(stderr
, "BINPLACE : error BNP0000: File '%s' is not listed in '%s'. Copying to dump.\n", FullFileName
, PlaceFileName
);
917 PutInDebug
? "Symbols" : (PutInLcDir
? BinplaceLcDir
: (DumpOverride
? DumpOverride
: DEFAULT_DUMP
)),
925 LPSTR SourceFileName
,
926 LPSTR SourceFilePart
,
927 LPSTR DestinationSubdir
,
928 LPSTR DestinationFilePart
931 CHAR DestinationFile
[MAX_PATH
+1];
932 CHAR TmpDestinationDir
[MAX_PATH
];
933 CHAR
*TmpSymbolFilePath
;
935 if ( !PlaceRootName
) {
936 fprintf(stderr
,"BINPLACE : warning BNP0000: PlaceRoot is not specified\n");
941 strcpy(DestinationFile
,PlaceRootName
);
942 strcat(DestinationFile
,"\\");
943 strcat(DestinationFile
,DestinationSubdir
);
944 strcat(DestinationFile
,"\\");
946 strcpy (TmpDestinationDir
, DestinationFile
);
949 if (!MakeSureDirectoryPathExists(DestinationFile
)) {
950 fprintf(stderr
, "BINPLACE : error BNP0000: Unable to create directory path '%s' (%u)\n",
951 DestinationFile
, GetLastError()
955 if (DestinationFilePart
) {
956 strcat(DestinationFile
,DestinationFilePart
);
958 strcat(DestinationFile
,SourceFilePart
);
962 (fVerbose
|| fTestMode
)) {
963 fprintf(stdout
,"BINPLACE : warning BNP0000: place %s in %s\n",SourceFileName
,DestinationFile
);
967 if (SourceIsNewer(SourceFileName
,DestinationFile
)) {
968 fprintf(stdout
, "binplace %s\n", SourceFileName
);
974 // In Setup mode, copy the file only if it's newer than
975 // the one that's already there.
977 if (SourceIsNewer(SourceFileName
,DestinationFile
)) {
979 fprintf(stdout
,"BINPLACE : warning BNP0000: copy %s to %s\n",SourceFileName
,DestinationFile
);
985 SetFileAttributes(DestinationFile
,FILE_ATTRIBUTE_NORMAL
);
988 if ( !CopyFile(SourceFileName
,DestinationFile
, FALSE
)) {
989 fprintf(stderr
,"BINPLACE : warning BNP0000: CopyFile(%s,%s) failed %d\n",SourceFileName
,DestinationFile
,GetLastError());
994 if (!fKeepAttributes
)
995 SetFileAttributes(DestinationFile
,FILE_ATTRIBUTE_NORMAL
);
998 TmpSymbolFilePath
= SymbolFilePath
;
1001 BinplaceCopyPdb(TmpSymbolFilePath
, SourceFileName
, TRUE
, FALSE
);
1002 // Copy the ILDB to be next to the exe
1003 BinplaceCopyIldb(TmpDestinationDir
, SourceFileName
, TRUE
, FALSE
);
1004 // Copy the manifest to be next to the exe
1005 BinplaceCopyManifest(TmpDestinationDir
, SourceFileName
, TRUE
, FALSE
);
1017 IN LPSTR SourceFile
,
1029 LPSTR DestinationFile
,
1030 LPSTR SourceFileName
,
1031 BOOL CopyFromSourceOnly
,
1035 CHAR Drive
[_MAX_DRIVE
];
1037 CHAR Filename
[_MAX_FNAME
];
1039 CHAR SourcePdbName
[_MAX_PATH
];
1040 CHAR DestinationPdbName
[_MAX_PATH
];
1042 _splitpath(SourceFileName
, Drive
, Dir
, Filename
, Ext
);
1043 _makepath(SourcePdbName
, Drive
, Dir
, Filename
, ".pdb");
1044 if (GetFileAttributesA(SourcePdbName
) != 0xffffffff) {
1046 // Source file exists
1048 strcpy(DestinationPdbName
, DestinationFile
);
1049 strcat(DestinationPdbName
, "\\");
1050 strcat(DestinationPdbName
, &Ext
[1]);
1051 strcat(DestinationPdbName
, "\\");
1052 strcat(DestinationPdbName
, Filename
);
1053 strcat(DestinationPdbName
, ".pdb");
1055 if (fVerbose
|| fTestMode
) {
1056 fprintf(stdout
,"BINPLACE : warning BNP0000: place %s in %s\n", SourcePdbName
, DestinationPdbName
);
1059 if (!MakeSureDirectoryPathExists(DestinationPdbName
)) {
1062 if (!CopyFileA(SourcePdbName
, DestinationPdbName
, FALSE
)) {
1065 SetFileAttributes(DestinationPdbName
,FILE_ATTRIBUTE_NORMAL
);
1073 LPSTR DestinationFile
,
1074 LPSTR SourceFileName
,
1075 BOOL CopyFromSourceOnly
,
1079 CHAR Drive
[_MAX_DRIVE
];
1081 CHAR Filename
[_MAX_FNAME
];
1083 CHAR SourceIldbName
[_MAX_PATH
];
1084 CHAR DestinationIldbName
[_MAX_PATH
];
1086 _splitpath(SourceFileName
, Drive
, Dir
, Filename
, Ext
);
1087 _makepath(SourceIldbName
, Drive
, Dir
, Filename
, ".ildb");
1088 if (GetFileAttributesA(SourceIldbName
) != 0xffffffff) {
1090 // Source file exists
1092 strcpy(DestinationIldbName
, DestinationFile
);
1093 strcat(DestinationIldbName
, "\\");
1094 strcat(DestinationIldbName
, Filename
);
1095 strcat(DestinationIldbName
, ".ildb");
1097 if (fVerbose
|| fTestMode
) {
1098 fprintf(stdout
,"BINPLACE : warning BNP0000: place %s in %s\n", SourceIldbName
, DestinationIldbName
);
1101 if (!MakeSureDirectoryPathExists(DestinationIldbName
)) {
1104 if (!CopyFileA(SourceIldbName
, DestinationIldbName
, FALSE
)) {
1107 SetFileAttributes(DestinationIldbName
,FILE_ATTRIBUTE_NORMAL
);
1114 BinplaceCopyManifest (
1115 LPSTR DestinationFile
,
1116 LPSTR SourceFileName
,
1117 BOOL CopyFromSourceOnly
,
1121 CHAR Drive
[_MAX_DRIVE
];
1123 CHAR Filename
[_MAX_FNAME
];
1125 CHAR SourceManifestName
[_MAX_PATH
];
1126 CHAR DestinationManifestName
[_MAX_PATH
];
1128 _splitpath(SourceFileName
, Drive
, Dir
, Filename
, Ext
);
1129 _makepath(SourceManifestName
, Drive
, Dir
, Filename
, Ext
);
1130 strcat(SourceManifestName
, ".manifest");
1132 if (GetFileAttributesA(SourceManifestName
) != 0xffffffff) {
1134 // Source file exists
1136 strcpy(DestinationManifestName
, DestinationFile
);
1137 strcat(DestinationManifestName
, "\\");
1138 strcat(DestinationManifestName
, Filename
);
1139 strcat(DestinationManifestName
, Ext
);
1140 strcat(DestinationManifestName
, ".manifest");
1142 if (fVerbose
|| fTestMode
) {
1143 fprintf(stdout
,"BINPLACE : warning BNP0000: place %s in %s\n", SourceManifestName
, DestinationManifestName
);
1146 if (!MakeSureDirectoryPathExists(DestinationManifestName
)) {
1149 if (!CopyFileA(SourceManifestName
, DestinationManifestName
, FALSE
)) {
1152 SetFileAttributes(DestinationManifestName
,FILE_ATTRIBUTE_NORMAL
);
1161 OUT PWIN32_FIND_DATA FindData
1168 FindHandle
= FindFirstFile(FileName
,FindData
);
1169 if (FindHandle
== INVALID_HANDLE_VALUE
) {
1172 FindClose(FindHandle
);